<template>
  <div class="upload-component">
    <!-- 已上传文件预览 -->
    <div v-if="value" class="file-preview">
      <div class="file-info">
        <el-icon><Document /></el-icon>
        <a :href="fileUrl" target="_blank" class="file-name">{{ getFileName(value) }}</a>
      </div>
      <div class="file-actions">
        <el-button type="danger" size="small" @click="clearFile">
          <el-icon><Delete /></el-icon>
        </el-button>
      </div>
    </div>
    
    <!-- 文件上传区域 -->
    <el-upload
      v-else
      action="#"
      :http-request="uploadFile"
      :show-file-list="false"
      :before-upload="beforeUpload"
      :disabled="isDisabled"
    >
      <div class="upload-area">
        <el-icon class="upload-icon"><Upload /></el-icon>
        <div class="upload-text">点击或拖拽文件到此处上传</div>
      </div>
    </el-upload>
  </div>
</template>

<script setup>
import { Upload, Document, Delete } from '@element-plus/icons-vue'
import { getToken } from '@/utils/auth'

const props = defineProps({
  item: {
    type: Object,
    required: true,
  },
  allDisabled: {
    type: Boolean,
    default: false
  }
})

const value = defineModel('value')
const proxy = inject('proxy')
const loading = ref(false)
const baseApiUrl = import.meta.env.VITE_APP_BASE_API
const emit = defineEmits(['uploadSuccess'])

// 计算文件URL
const fileUrl = computed(() => {
  if (!value.value) return ''
  return value.value.startsWith('http') 
    ? value.value 
    : baseApiUrl + value.value
})

// 计算组件是否禁用
const isDisabled = computed(() => {
  return props.allDisabled || props.item.config?.disabled || loading.value
})

// 获取文件名
function getFileName(path) {
  if (!path) return ''
  const parts = path.split('/')
  return parts[parts.length - 1]
}

// 上传前校验
function beforeUpload(file) {
  // 文件类型限制
  const acceptTypes = props.item.config?.accept?.split(',') || []
  if (acceptTypes.length > 0) {
    const fileExt = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()
    const found = acceptTypes.some(type => {
      if (type.startsWith('.')) {
        // 扩展名匹配
        return type.substring(1).toLowerCase() === fileExt
      } else {
        // MIME类型匹配
        return file.type.match(type)
      }
    })
    
    if (!found) {
      proxy.$modal.msgError(`文件格式不符合要求，请上传${acceptTypes.join(', ')}类型的文件`)
      return false
    }
  }
  
  // 文件大小限制
  const maxSize = props.item.config?.maxSize || 5 // 默认5MB
  if (file.size / 1024 / 1024 > maxSize) {
    proxy.$modal.msgError(`文件大小不能超过 ${maxSize}MB`)
    return false
  }
  
  return true
}

// 文件上传
async function uploadFile({ file }) {
  if (loading.value) return
  loading.value = true
  
  try {
    let formData = new FormData()
    formData.append('file', file)
    
    // 使用fetch上传文件
    const response = await fetch(baseApiUrl + '/common/upload', {
      method: 'POST',
      body: formData,
      headers: {
        'Authorization': 'Bearer ' + getToken()
      }
    }).then(res => res.json())
    
    if (response.code === 200 && response.fileName) {
      value.value = response.fileName
      proxy.$modal.notifySuccess('文件上传成功')
      
      // 触发上传成功事件，将文件信息传递出去
      emit('uploadSuccess', response, file)
    } else {
      throw new Error(response.msg || '上传失败')
    }
  } catch (error) {
    proxy.$modal.msgError(error?.message || '上传失败')
  } finally {
    loading.value = false
  }
}

// 清除文件
function clearFile() {
  value.value = ''
}

// 导出获取ref的方法，用于BaseForm
function getRef() {
  return null
}

defineExpose({
  getRef
})
</script>

<style scoped lang="scss">
.upload-component {
  width: 100%;
}

.upload-area {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 120px;
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  transition: var(--el-transition-duration-fast);
  
  &:hover {
    border-color: var(--el-color-primary);
  }
  
  .upload-icon {
    font-size: 28px;
    color: #8c939d;
    margin-bottom: 8px;
  }
  
  .upload-text {
    font-size: 14px;
    color: #8c939d;
  }
}

.file-preview {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 6px;
  
  .file-info {
    display: flex;
    align-items: center;
    
    .el-icon {
      margin-right: 8px;
      color: var(--el-text-color-secondary);
    }
    
    .file-name {
      color: var(--el-text-color-primary);
      max-width: 250px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      text-decoration: none;
      
      &:hover {
        color: var(--el-color-primary);
        text-decoration: underline;
      }
    }
  }
}
</style> 